package java_thinking.unit_12;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * @Description : 编写构造器时需要注意的异常处理，构造器就有可能抛出异常，有些对象在
 *              构造器抛出异常之前可能还没成功创建，而这些对象在finally子句中确实要被清理的
 * @author: cww
 * @DateTime: 2019-03-24 14:32
 */

public class InputFile {
    private BufferedReader in;
    public InputFile(String fname) throws Exception {
        try {
            in = new BufferedReader(new FileReader(fname));
        } catch (FileNotFoundException e) {
            //这时要注意文件还没有被打开，所以这里不能执行in.close()
            System.out.println("Could not open" + fname);
            throw e;
        } catch (Exception e) {
            //其余异常就要关闭文件流了
            try {
                in.close();
            } catch (IOException e1) {
                System.out.println("File close failed");
            }
            //重新抛出异常
            throw e;
        } finally {
            //不要在这里关闭文件流，原因与上面的fileNotFoundException一样
            System.out.println("finally");
        }
    }

    public String getLine() {
        String s;
        try {
            s = in.readLine();
        } catch (IOException e) {
            throw new RuntimeException("readLine failed");
        }
        return s;
    }
    public void dispose(){
        try {
            in.close();
            System.out.println("dispose successful");
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }
}

class Cleanup {
    public static void main(String[] args) {
        try {
            //InputFile的构造仅在外部的try块有效，如果构造失败，进入外部catch子句，而dispose()
            //不会被调用
            InputFile inputFile = new InputFile("Cleanup.class");
            try {
                String s ;
                int i = 1;
                while ((s = inputFile.getLine())!=null){
                    System.out.println("getLine successful");
                }
            } catch (Exception e) {
                System.out.println("Caught Exception in maindemo");
                e.printStackTrace(System.out);
            } finally {
                //当InputFile构造成功后就应该要在任何情况下都要执行finally内的dispose()
                //而InputFile构造失败时这里是不会执行的
                inputFile.dispose();
            }
        } catch (Exception e) {
            System.out.println("InputFile construction failed");
        }
    }
}
